package br.edu.delta.controller;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Collection;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import br.edu.delta.dto.LivroDevolucaoDTO;
import br.edu.delta.exception.NegocioException;
import br.edu.delta.form.DevolucaoForm;
import br.edu.delta.model.Devolucao;
import br.edu.delta.model.Emprestimo;
import br.edu.delta.model.Leitor;
import br.edu.delta.model.Livro;
import br.edu.delta.service.DevolucaoService;
import br.edu.delta.util.Util;

/**
 * <p>
 * <b>Title:</b> EmprestimoController
 * </p>
 * 
 * <p>
 * <b>Description:</b> EmprestimoController
 * </p>
 * 
 * <p>
 * <b>Company: </b>
 * </p>
 * 
 * @author Denis
 * 
 * @version 1.0.0
 */
@Named
@RequestScoped
public class DevolucaoController extends AppController {

	/** Atributo serialVersionUID. */
	private static final long serialVersionUID = -1L;

	/** Atributo service. */
	@Inject
	private DevolucaoService service;

	/** Atributo formulario. */
	@Inject
	private DevolucaoForm formulario;

	/**
	 * @see br.edu.delta.controller.AppController#iniciarDados()
	 */
	@Override
	public void iniciarDados() {

		this.getFormulario().setEntidade(new Devolucao());

		this.getFormulario().getEntidade().setLivro(new Livro());

		this.getFormulario().setEmprestimo(new Emprestimo());

		this.getFormulario().getEntidade().setEmprestimo(new Emprestimo());

		this.getFormulario().getListaLivrosDevolucao().clear();

		this.getFormulario().setMostrarPainelDatas(false);

		this.getFormulario().setValorTotalMulta(new BigDecimal(0));
	}

	/**
	 * Método responsável por retornar lista de nomes de leitores
	 * 
	 * @author Denis
	 * 
	 * @param nome
	 * @return
	 */
	public Collection<String> pesquisarLeitores(String nome) {

		return this.getService().pesquisarLeitores(nome);
	}

	/**
	 * Método responsável por pesquisar leitor por id
	 * 
	 * @author Denis
	 * 
	 */
	public void pesquisarLeitorPorId() {

		Leitor leitor = this.getService().pesquisarLeitorPorId(this.getFormulario().getEntidade().getEmprestimo().getLeitor().getId());

		this.getFormulario().getEntidade().getEmprestimo().setLeitor(new Leitor());

		obterEmprestimoLeitor(leitor);
	}

	private void obterEmprestimoLeitor(Leitor leitor) {

		if (!Util.isNull(leitor)) {

			this.getFormulario().setMostrarPainelDatas(false);

			this.getFormulario().getEntidade().getEmprestimo().setLeitor(leitor);

			this.getFormulario().getListaLivrosDevolucao().clear();

			this.getFormulario().setEmprestimo(this.getService().obterEmprestimo(leitor));

			if (!Util.isNullOuVazio(this.getFormulario().getEmprestimo())) {

				for (Livro livro : this.getFormulario().getEmprestimo().getLivros()) {

					if (!this.getService().isLivroDevolvido(livro.getId(), this.getFormulario().getEmprestimo().getId())) {

						LivroDevolucaoDTO itemLista = new LivroDevolucaoDTO();

						itemLista.setDataEmprestimo(this.getFormulario().getEmprestimo().getDataCadastro());

						itemLista.setId(livro.getId());

						itemLista.setCodigo(livro.getCodigo());

						itemLista.setDescricao(livro.getNome() + " - Autor(es) " + livro.getAutores() + " - Editora " + livro.getEditora());

						itemLista.setQtdDiasAtraso(calcularDiasAtraso(this.getFormulario().getEmprestimo()));

						if (!Util.isNullOuVazio(itemLista.getQtdDiasAtraso())) {
							itemLista.setValorMulta(new BigDecimal(itemLista.getQtdDiasAtraso() * this.getService().obterValorMulta()));
							this.getFormulario().setValorTotalMulta(this.getFormulario().getValorTotalMulta().add(itemLista.getValorMulta()));
						} else {
							itemLista.setValorMulta(new BigDecimal(0));
						}

						this.getFormulario().getListaLivrosDevolucao().add(itemLista);

					}
				}

				this.getFormulario().setMostrarPainelDatas(true);

				if (this.getFormulario().getListaLivrosDevolucao().isEmpty()) {

					this.getFormulario().setMostrarPainelDatas(false);

					this.getFormulario().setValorTotalMulta(new BigDecimal(0));

					AppController.messageInfo("Leitor não possui livros a serem devolvidos!");

				}

			} else {

				this.getFormulario().setMostrarPainelDatas(false);

				this.getFormulario().setValorTotalMulta(new BigDecimal(0));

				AppController.messageInfo("Leitor não possui livros a serem devolvidos!");
			}

		} else {

			this.getFormulario().getEntidade().getEmprestimo().setLeitor(new Leitor());

			this.getFormulario().getListaLivrosDevolucao().clear();

			this.getFormulario().setValorTotalMulta(new BigDecimal(0));

			AppController.messageError("Leitor não Encontrado!");
		}
	}

	private Integer calcularDiasAtraso(Emprestimo emprestimo) {

		if (emprestimo.getDataMaximaDevolucao().before(getDataAtual())) {

			int MILLIS_IN_DAY = 86400000;
			Calendar c1 = Calendar.getInstance();
			c1.setTime(emprestimo.getDataMaximaDevolucao());
			c1.set(Calendar.MILLISECOND, 0);
			c1.set(Calendar.SECOND, 0);
			c1.set(Calendar.MINUTE, 0);
			c1.set(Calendar.HOUR_OF_DAY, 0);

			Calendar c2 = Calendar.getInstance();
			c2.setTime(getDataAtual());
			c2.set(Calendar.MILLISECOND, 0);
			c2.set(Calendar.SECOND, 0);
			c2.set(Calendar.MINUTE, 0);
			c2.set(Calendar.HOUR_OF_DAY, 0);

			return (int) ( ( c2.getTimeInMillis() - c1.getTimeInMillis() ) / MILLIS_IN_DAY );

		} else {

			return 0;
		}
	}

	public boolean isListaLivrosEmpty() {

		return this.getFormulario().getListaLivrosDevolucao().isEmpty();

	}

	/**
	 * Método responsável por pesquisar leitor por nome
	 * 
	 * @author Denis
	 * 
	 */
	public void pesquisarLeitorPorNome() {

		Leitor leitor = this.getService().pesquisarLeitorPorNome(this.getFormulario().getEntidade().getEmprestimo().getLeitor().getNome());

		this.getFormulario().getEntidade().getEmprestimo().setLeitor(new Leitor());

		obterEmprestimoLeitor(leitor);

	}

	/**
	 * Método responsável por pesquisar livros por código
	 * 
	 * @author Denis
	 * 
	 */
	public void pesquisarLivroPorCodigo() {

		Livro livro = this.getService().pesquisarLivroPorCodigo(this.getFormulario().getEntidade().getLivro().getCodigo());

		this.getFormulario().getEntidade().setLivro(new Livro());

		if (!Util.isNull(livro)) {

			this.getFormulario().getEntidade().setLivro(livro);
		} else {

			this.getFormulario().getEntidade().setLivro(new Livro());

			AppController.messageError("Livro não Encontrado!");
		}
	}

	public void devolverTodosLivros() {

		try {

			for (LivroDevolucaoDTO livroDevolucaoDTO : this.getFormulario().getListaLivrosDevolucao()) {

				this.getFormulario().getEntidade().setEmprestimo(this.getFormulario().getEmprestimo());

				this.getFormulario().getEntidade().setLivro(this.getService().obterLivro(livroDevolucaoDTO.getId()));

				this.getFormulario().getEntidade().setQtdDiasAtraso(livroDevolucaoDTO.getQtdDiasAtraso());

				this.getFormulario().getEntidade().setValorMulta(livroDevolucaoDTO.getValorMulta());

				this.getService().salvar(this.getFormulario().getEntidade());

			}
			
			this.getFormulario().getListaLivrosDevolucao().clear();
			
			AppController.messageInfo("Os Livros foram Devolvidos com Sucesso!");

			Emprestimo emprestimo = this.getFormulario().getEntidade().getEmprestimo();

			this.getFormulario().setEntidade(new Devolucao());

			this.getFormulario().getEntidade().setEmprestimo(emprestimo);

		} catch (NegocioException e) {

			AppController.messageError(e.getMessage());
		}

	}

	public void devolverLivro(LivroDevolucaoDTO livroDevolucaoDTO) {

		try {

			this.getFormulario().getEntidade().setEmprestimo(this.getFormulario().getEmprestimo());

			this.getFormulario().getEntidade().setLivro(this.getService().obterLivro(livroDevolucaoDTO.getId()));

			this.getFormulario().getEntidade().setQtdDiasAtraso(livroDevolucaoDTO.getQtdDiasAtraso());

			this.getFormulario().getEntidade().setValorMulta(livroDevolucaoDTO.getValorMulta());

			this.getService().salvar(this.getFormulario().getEntidade());

			this.getFormulario().getListaLivrosDevolucao().remove(livroDevolucaoDTO);

			AppController.messageInfo("Livro Devolvido com Sucesso!");

			Emprestimo emprestimo = this.getFormulario().getEntidade().getEmprestimo();

			this.getFormulario().setEntidade(new Devolucao());

			this.getFormulario().getEntidade().setEmprestimo(emprestimo);

		} catch (NegocioException e) {

			AppController.messageError(e.getMessage());
		}

	}

	/**
	 * Método responsável por pesquisar livro por nome
	 * 
	 * @author Denis
	 * 
	 */
	public void pesquisarLivroPorNome() {

		Livro livro = this.getService().pesquisarLivroPorNome(this.getFormulario().getEntidade().getLivro().getNome());

		this.getFormulario().getEntidade().setLivro(new Livro());

		if (!Util.isNull(livro)) {

			this.getFormulario().getEntidade().setLivro(livro);
		} else {

			this.getFormulario().getEntidade().setLivro(new Livro());

			AppController.messageError("Livro não Encontrado!");
		}
	}

	/**
	 * Retorna o valor do atributo <code>service</code>
	 * 
	 * @return <code>DevolucaoService</code>
	 */
	public DevolucaoService getService() {

		return service;
	}

	/**
	 * Retorna o valor do atributo <code>formulario</code>
	 * 
	 * @return <code>DevolucaoForm</code>
	 */
	public DevolucaoForm getFormulario() {

		return formulario;
	}

}
